/**
 * @version 1.0
 * @created 07 Decemeber 2010
 *
 * AuthenticationServiceImplementor
 *
 * Copyright @ 2010
 * All Rights Reserved.
 * CONFIDENTIAL AND TRADE SECRET
 * 
 */
package com.ces.knacky.framework.security;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl;

import com.ces.knacky.framework.security.model.AuthenticatedUser;
import com.ces.knacky.framework.services.CommonService;
import com.ces.knacky.model.RoleTable;
import com.ces.knacky.model.UserTable;

/**
 * It is used to populate user and their respective roles and authorize them for further operation.
 * It inherits <class>JdbcDaoImpl</class> which provide basic bone for creating our own JDBC 
 * security implementor when the schema is different from the default-schema understood by spring
 * security underlying API.
 *    
 * @author bipul_sinha
 *
 */
public class AuthenticationServiceImplementor extends JdbcDaoImpl {
	@Autowired(required = true)
	private CommonService commonService;
	
	@Override
	protected List<GrantedAuthority> loadUserAuthorities(String username) {
		List<RoleTable> roleList = (List<RoleTable>) commonService.list("select rt from RoleTable as rt " +
				"inner join rt.userRoles as ur " +
				"inner join ur.user as ut " +				
				"where ut.description = '" + username +"'");
		List<GrantedAuthority> grantedAuthorityList = new ArrayList <GrantedAuthority>();
		for (RoleTable roleTable : roleList) {
			GrantedAuthority grantedAuthority = new GrantedAuthorityImpl(roleTable.getDescription());	
			grantedAuthorityList.add(grantedAuthority);
		}
		System.out.println("GrantedAuthorityList::" + grantedAuthorityList);
		return grantedAuthorityList;
	}

	@Override
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException, DataAccessException {
		UserTable user = (UserTable) commonService.findFirstByDescription(UserTable.class, username);
		if (user != null) {
			List <GrantedAuthority> grantedAuthorityList =  loadUserAuthorities(username);
			GrantedAuthority []authority = new GrantedAuthorityImpl[grantedAuthorityList.size()];
			authority = grantedAuthorityList.toArray(authority);
			return new AuthenticatedUser(user.getDescription(), user.getPwd(), user.getEmailId(),true, true, true, true, authority);
		}
		throw new UsernameNotFoundException(messages.getMessage("JdbcDaoImpl.notFound", 
				new Object[]{username}, "Username {0} not found"), username);  
	}

	/**
	 * Returns CommonService object to perform business operations.
	 * 
	 * @return 	commonService
	 * 			Returns CommonService object to perform business operations.
	 */
	public CommonService getCommonService() {
		return commonService;
	}

	/**
	 * Used to set CommonService object wired through beans configuration file.
	 * 
	 * @param 	commonService
	 * 			CommonService to perform business operation. 
	 */
	public void setCommonService(CommonService commonService) {
		this.commonService = commonService;
	}

}
